﻿package gui.hug;

	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.display.MovieClip;
	import flash.text.TextField;
	import flash.utils.Timer;
	import flash.events.TimerEvent;

class HUGComboBox extends HUGSprite {
	private var wrapper : Dynamic;
	private var txt : TextField;
	private var da_bg : HUGSprite; // "Down Arrow" BackGround
	private var dd : HUGListBox; // DropDown
	private var mouseOver : Bool;
	private var timer : Timer;
	
	private static inline var W : UInt = 16; // width of "Down Arrow BackGround"
	private static inline var H : UInt = 21; // height of the text field
 
	private static inline var TIMER_DELAY : UInt = 33;

	public function new(wrapper : Dynamic, x : Int, y : Int, w : Int) {
		super();
		this.x = x;
		this.y = y;
		this.wrapper = wrapper;
		mouseOver = false;
		buttonMode = true;
		timer = new Timer(TIMER_DELAY, 0);
		
		// BackGround
		var bg : HUGSprite = new HUGSprite();
		Utils.fillRect(bg, 0, 0, w, H, 0xffffff);
		addChild(bg);

		// Arrow BackGround
		da_bg = new HUGSprite();
		Utils.fillRect(da_bg, 0, 0, W, H, Utils.ARROW_BG_COL);
		Utils.vertLine(da_bg, 0, 0, H-0.5, Utils.ARROW_BG_BORDER_COL);
		da_bg.x = w - W;
		da_bg.y = 0.5;
		da_bg.alpha = 0;
		da_bg.mouseEnabled = false;
		addChild(da_bg);

		// Border and "Down Arrow"
		var rc : HUGSprite = new HUGSprite();
		var rc_x : Int = w - 11;
		Utils.hollowRect(rc, 0, 0, w, H, Utils.BORDER2_COL);
		Utils.drawArrow(rc, rc_x, 9, true);
		rc.mouseEnabled = false;
		addChild(rc);

		// Text field
		txt = Utils.addText(4, 2, w - W, 11, "");
		txt.mouseEnabled = false;
		addChild(txt);

		// Drop down
		dd = new HUGListBox(0, H, w);
		dd.visible = false;
		dd.owner = this;
		addChild(dd);

		//
		bg.addEventListener(MouseEvent.MOUSE_DOWN, onClick);
		addEventListener(MouseEvent.ROLL_OVER, onOver);
		if (wrapper != null)
		wrapper.addEventListener("onWindowBlur", onWindowBlur);
	}

	public function clear() {
		dd.clear();
	}

	public function addItemsArray(arr : Array<Dynamic>) {
		var length = dd.getLength();
		if (length == 0 && arr.length > 0)
			setCurTxt(arr[0]);
		dd.addItemsArray(arr);
	}

	public function addItem(s : String)	{
		var length = dd.getLength();
		if (length == 0)
			setCurTxt(s);
		dd.addItem(s);
	}

	public function getSelectedIndex() : Int {
		return dd.getSelectedIndex();
	}

	public function setSelectedIndex(idx : Int) {
		dd.setSelectedIndex(idx);
	}

	public function getLength() : Float	{
		return dd.getLength();
	}

	public function getWidth() : Float {
		return dd.getWidth();
	}

	public function getHeight() : Float	{
		return dd.y + (dd.visible ? dd.getHeight() : 0);
	}

	// ---------------------------------------------------------------------------- internal methods.
	public function onItemClick(item : Dynamic, b : Bool) {
		setCurTxt(item.txt.text);
		dispatchEvent(new Event(Event.CHANGE));
		if (b)
			showDropDown(!dd.visible);
	}

	// ---------------------------------------------------------------------------- private methods.
	private function setCurTxt(s : String) {
		txt.text = s;
		txt.setTextFormat(Utils.getTxtFormat(11, 0));
	}

	private function showDropDown(b : Bool)	{
		if (root == null)
			return;
		dd.reset();
		if (b) {
			// Show DropDown
			dd.visible = true;

			//(parent as DisplayObjectContainer).setChildIndex(this, (parent as DisplayObjectContainer).numChildren - 1);
			this.parent.setChildIndex(this, parent.numChildren - 1);

			//WARNING
			// Keys control
			//Utils.topParent(this).addEventListener(KeyboardEvent.KEY_DOWN, dd.onComboKeyDown);
			this.addEventListener(KeyboardEvent.KEY_DOWN, dd.onComboKeyDown);

			/*if (wrapper != null)
			{
			if (wrapper.parent as DisplayObject != null)
			wrapper.parent.addEventListener(KeyboardEvent.KEY_DOWN, dd.onComboKeyDown);
			else
			wrapper.addEventListener(KeyboardEvent.KEY_DOWN, dd.onComboKeyDown);
			}*/

			//
			root.addEventListener(MouseEvent.MOUSE_DOWN, onStageClick);
			MouseWheel.capture();
		} else {
			// Hide DropDown
			dd.visible = false;
			if (!mouseOver)
			da_bg.alpha = 0.0;

			//Warning
			// Keys control
			Utils.topParent(this).removeEventListener(KeyboardEvent.KEY_DOWN, dd.onComboKeyDown);
			//this.removeEventListener(KeyboardEvent.KEY_DOWN, dd.onComboKeyDown);
			/*if (wrapper != null)
			{
			if (wrapper.parent as DisplayObject != null)
			wrapper.parent.removeEventListener(KeyboardEvent.KEY_DOWN, dd.onComboKeyDown);
			else
			wrapper.removeEventListener(KeyboardEvent.KEY_DOWN, dd.onComboKeyDown);
			}*/
			//
			root.removeEventListener(MouseEvent.MOUSE_DOWN, onStageClick);
			MouseWheel.release();
		}
		dispatchEvent(new Event(Event.RESIZE));
	}

	// ----------------------------------------------------------------------- Over/Out animation
	private function timerHandler1(e : TimerEvent) {
		da_bg.alpha += 0.2;
		if (da_bg.alpha >= 1.0)	{
			da_bg.alpha = 1.0;
			timer.stop();
		}
	}

	private function timerHandler2(e : TimerEvent) {
		da_bg.alpha -= 0.2;
		if (da_bg.alpha <= 0.0) {
			da_bg.alpha = 0.0;
			timer.stop();
		}
	}

	private function startAnim(over : Bool)	{
		if (timer.running)
			timer.stop();
		timer = new Timer(TIMER_DELAY, 5);
		timer.addEventListener(TimerEvent.TIMER, over ? timerHandler1 : timerHandler2);
		timer.start();
	}

	// ----------------------------------------------------------------------- Event handlers
	private function onWindowBlur(e : Dynamic) {
		if (dd.visible)
			showDropDown(false);
	}

	private function onOver(e : MouseEvent)	{
		mouseOver = true;
		removeEventListener(MouseEvent.ROLL_OVER, onOver);
		addEventListener(MouseEvent.ROLL_OUT, onOut);
		startAnim(true);
	}

	private function onOut(e : MouseEvent) {
		mouseOver = false;
		removeEventListener(MouseEvent.ROLL_OUT, onOut);
		addEventListener(MouseEvent.ROLL_OVER, onOver);
		if (!dd.visible)
			startAnim(false);
	}

	private function onClick(e : MouseEvent) {
		showDropDown(!dd.visible);
	}

	private function onStageClick(e : MouseEvent) {
		//Warning
		// if (!contains(e.target as DisplayObject))
		if (!contains(e.target))
			showDropDown(false);
	}
}
